package com.example.selfservicestation.mob

import android.content.Context
import com.example.selfservicestation.R
import com.example.selfservicestation.constant.SCANNER_MIN_INTERVAL_SECONDS
import com.example.selfservicestation.event.CardEvent
import com.example.selfservicestation.extensions.times
import com.example.selfservicestation.util.Logger
import com.example.selfservicestation.util.jvmSeconds
import com.example.selfservicestation.util.showToast
import org.greenrobot.eventbus.EventBus
import java.util.*
import kotlin.experimental.xor

/**
 * 高级扫码解析器
 */
@Suppress("BooleanMethodIsAlwaysInverted")
class AdvanceScanParser(
    val listener: (eve: CardEvent) -> Unit
) {

    class ScanDataListener(val key: Any, val listener: (ScanData) -> Unit)

    private val scanDataListeners = ArrayList<ScanDataListener>()

    fun registerScanDataListener(key: Any, listener: (ScanData) -> Unit) {
        scanDataListeners.add(ScanDataListener(key, listener))
        executeIdentityListener = false
    }

    fun unregisterScanDataListener(key: Any) {
        val it = scanDataListeners.iterator()
        while (it.hasNext()) {
            if (it.next().key == key) {
                it.remove()
            }
        }
        executeIdentityListener = scanDataListeners.isEmpty()
    }

    private var executeIdentityListener = true

    /**
     * 最近 3 秒内的刷卡记录
     */
    private val histories = LinkedList<Content>()

    class Content(
        val data: ByteArray,
        val time: Long
    )

    fun onScanDataRead(ctx: Context, data: ByteArray, scannerId: Any,index: Int) {
        // 同一张卡，3秒内只能刷一次
        val dataHexStr = data.toHexString()
//        synchronized(this) {
//            val now = jvmSeconds()
//            while (histories.isNotEmpty() && now - histories.first.time >= SCANNER_MIN_INTERVAL_SECONDS) {
//                histories.removeFirst()
//            }
//            if (histories.find { it.data.contentEquals(data) } != null) {
//                Logger.d(
//                    "SCANNER",
//                    "扫码头 $SCANNER_MIN_INTERVAL_SECONDS 秒内重复输入：${data.toHexString()}"
//                )
//                return
//            }
//            Logger.d("SCANNER", "扫码头输入：${dataHexStr}")
//            histories.addLast(Content(data, now))
//        }

        if (dataHexStr.startsWith("AA 77")) {
            if (data.size == 12) {
                if (!verifyChecksumByXor(data)) {
                    return
                }
                var cardNo =
                    (data[2].toUByte() * 256u * 256u * 256u + data[3].toUByte() * 256u * 256u + data[4].toUByte() * 256u + data[5].toUByte()).toString()
                if (cardNo.length < 10) {
                    cardNo = "0".times(10 - cardNo.length) + cardNo
                }
                val userIdArr = byteArrayOf(data[6], data[7], data[8], data[9], data[10])
                val userId = if (userIdArr.all { it == 0.toByte() }) {
                    ""
                } else {
                    userIdArr.toHexString(false)
                }
                Logger.i("SCANNER", "刷卡板数据解析: 卡号: $cardNo, 用户ID: $userId")
                val realCardNo = userId.ifEmpty { cardNo }
                val scanData = ScanData(index,true, realCardNo)
                if (!executeIdentityListener) {
                    scanDataListeners.forEach { it.listener(scanData) }
                    return
                }
            }
        } else if (dataHexStr.startsWith("55 AA")) {
            if (data.size > 5) {
                if (!verifyChecksumByXor(data)) {
                    return
                }
                var cardNo =
                    (data[2].toUByte() * 256u * 256u * 256u + data[3].toUByte() * 256u * 256u + data[4].toUByte() * 256u + data[5].toUByte()).toString()
                if (cardNo.length < 10) {
                    cardNo = "0".times(10 - cardNo.length) + cardNo
                }
                Logger.i("SCANNER", "刷卡板数据(解析后的卡号): $cardNo")
                val scanData = ScanData(index,true, cardNo)
                if (!executeIdentityListener) {
                    scanDataListeners.forEach { it.listener(scanData) }
                    return
                }
            }
        } else {
            val result = ScanParser.getInstance(scannerId).parse((scannerId as PortManager).index,data)
            Logger.d("SCANNER", "解析：${result}")
            if (result == null) {
                showToast("未识别，请重新扫码或刷卡")
                return
            }
            if (result is BrokenScanData) {
                return  // 扫码头断包输入
            }
            if (!executeIdentityListener) {
                scanDataListeners.forEach { it.listener(result) }
                return
            }
        }
    }

    private fun verifyChecksumByXor(data: ByteArray) : Boolean {
        if (data.size < 2) {
            return false
        }
        var checksum = data[0]
        for (i in 1 until data.size - 1) {
            checksum = checksum xor data[i]
        }
        return data[data.size - 1] == checksum
    }

}